Jose M Sallan
MBA en Business Analytics
Visualizando con ggplot
Manipulación de datos con dplyr
Leyendo .csv con readr
Leyendo Excel con readxl
Transformación de tablas con tidyr
Comunicando resultados con rmarkdown
Cargamos tidyverse haciendo:
Visualizing with ggplot
ggplot2 crea gráficos con la gramática de gráficos:
data: datos en forma tabular.mapping: variables a mostrar.geom: gráfico a mostrar.Los famosos datos iris de Fisher o Anderson recogen las medidas en centímetros de la longitud (length) y anchura (width) de los sépalos (sepal) y pétalos (petal) de 50 flores de cada una de las tres especies de iris: setosa, versicolor and virginica.
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
¿Cómo podemos representar la relación entre Sepal.Length y Sepal.Width?
Creemos un gráfico de dispersión congeom_point():
Añadimos geom_smooth() para añadir una línea de tendencia.
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
Podemos asignar un color a cada categoría (especie) haciendo color = Species en mapping:
color no define qué colores usamos, sino la información que transmitimos usando color.
Definamos una línea de regresión para cada categoría con geom_smooth(method = "lm")
ggplot(data = iris, mapping = aes(Sepal.Length, Sepal.Width, col = Species)) +
geom_point() +
geom_smooth(method = "lm")## `geom_smooth()` using formula 'y ~ x'
En vez de usar color, podemos definir un gráfico en facetas.
ggplot(data = iris, mapping = aes(Sepal.Length, Sepal.Width)) +
geom_point() +
geom_smooth(method = "lm") +
facet_grid(. ~ Species)## `geom_smooth()` using formula 'y ~ x'
¿Cómo se comporta Sepal.Length para cada Species?
Podemos usar un boxplot:
ggplot(data = iris, mapping = aes(Species, Sepal.Length)) +
geom_boxplot(fill = c("#FF9933", "#6666FF", "#B2FF66"))Más colores en: https://www.rapidtables.com/web/color/RGB_Color.html
ggplot(data = iris, mapping = aes(Species, Sepal.Length)) +
stat_summary(fun.min = min, fun.max = max, fun = median)mtcars procede de la edición de 1974 de la revista Motor Trend US, e incluye consumo de combustible y diez aspectos de diseño y desempeño para 32 automóviles.
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
¿Cuántos modelos tienen motores de cada uno de los valores de número de cilindros cyl?
Transformamos cyl de entera a categórica para hacer un gráfico de barras con geom_bar().
Para crear el gráfico, geom_bar() cuenta el número de observaciones en cada categoría.
¿Cuántos modelos de cada número de cilindros tiene cambio automático o manual?
¿Cuántos modelos de cada número de cilindros tiene cambio automático o manual?
Volvamos a iris: ¿Cuál es la distribución de Sepal.Length?
Podemos visualizarlas con histogramas o gráficos de densidad.
Generamos histograma con geom_histogram(bins = 10). Hemos de especificar el número de barras con bins.
Refinando la estética:
ggplot(data = iris, mapping = aes(Sepal.Length)) +
geom_histogram(bins = 10, fill = "#CCFFFF", color = "#808080")fill y color no están en mapping, así que no estamos transmitiendo información adicional con el color.
Generamos gráficos de densidad con geom_density().
Los verbos básicos de manipulación de datos:
filter para filtrar filas por valor.select para seleccionar columnas.arrange para ordenar tablas por una o varias variables.mutate para añadir nuevas variables.summarise para obtener valores resumen.tibble es la versión de tidyverse del data frame.
## # A tibble: 150 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # … with 140 more rows
## # A tibble: 6 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 7.6 3 6.6 2.1 virginica
## 2 7.7 3.8 6.7 2.2 virginica
## 3 7.7 2.6 6.9 2.3 virginica
## 4 7.7 2.8 6.7 2 virginica
## 5 7.9 3.8 6.4 2 virginica
## 6 7.7 3 6.1 2.3 virginica
## # A tibble: 9 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 7 3.2 4.7 1.4 versicolor
## 2 6.9 3.1 4.9 1.5 versicolor
## 3 6.5 2.8 4.6 1.5 versicolor
## 4 6.6 2.9 4.6 1.3 versicolor
## 5 6.7 3.1 4.4 1.4 versicolor
## 6 6.6 3 4.4 1.4 versicolor
## 7 6.8 2.8 4.8 1.4 versicolor
## 8 6.7 3 5 1.7 versicolor
## 9 6.7 3.1 4.7 1.5 versicolor
To arrange means ordering by a colum or columns
## # A tibble: 150 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 4.3 3 1.1 0.1 setosa
## 2 4.4 2.9 1.4 0.2 setosa
## 3 4.4 3 1.3 0.2 setosa
## 4 4.4 3.2 1.3 0.2 setosa
## 5 4.5 2.3 1.3 0.3 setosa
## 6 4.6 3.1 1.5 0.2 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 4.6 3.6 1 0.2 setosa
## 9 4.6 3.2 1.4 0.2 setosa
## 10 4.7 3.2 1.3 0.2 setosa
## # … with 140 more rows
Decreasing order:
## # A tibble: 150 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 7.9 3.8 6.4 2 virginica
## 2 7.7 3.8 6.7 2.2 virginica
## 3 7.7 2.6 6.9 2.3 virginica
## 4 7.7 2.8 6.7 2 virginica
## 5 7.7 3 6.1 2.3 virginica
## 6 7.6 3 6.6 2.1 virginica
## 7 7.4 2.8 6.1 1.9 virginica
## 8 7.3 2.9 6.3 1.8 virginica
## 9 7.2 3.6 6.1 2.5 virginica
## 10 7.2 3.2 6 1.8 virginica
## # … with 140 more rows
By two variables
## # A tibble: 150 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.8 4 1.2 0.2 setosa
## 2 5.7 4.4 1.5 0.4 setosa
## 3 5.7 3.8 1.7 0.3 setosa
## 4 5.5 4.2 1.4 0.2 setosa
## 5 5.5 3.5 1.3 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 5.4 3.7 1.5 0.2 setosa
## 8 5.4 3.9 1.3 0.4 setosa
## 9 5.4 3.4 1.7 0.2 setosa
## 10 5.4 3.4 1.5 0.4 setosa
## # … with 140 more rows
## # A tibble: 150 × 2
## Sepal.Length Sepal.Width
## <dbl> <dbl>
## 1 5.1 3.5
## 2 4.9 3
## 3 4.7 3.2
## 4 4.6 3.1
## 5 5 3.6
## 6 5.4 3.9
## 7 4.6 3.4
## 8 5 3.4
## 9 4.4 2.9
## 10 4.9 3.1
## # … with 140 more rows
## # A tibble: 150 × 4
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## <dbl> <dbl> <dbl> <dbl>
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3 1.4 0.2
## 3 4.7 3.2 1.3 0.2
## 4 4.6 3.1 1.5 0.2
## 5 5 3.6 1.4 0.2
## 6 5.4 3.9 1.7 0.4
## 7 4.6 3.4 1.4 0.3
## 8 5 3.4 1.5 0.2
## 9 4.4 2.9 1.4 0.2
## 10 4.9 3.1 1.5 0.1
## # … with 140 more rows
Usando tidyselect:
## # A tibble: 150 × 2
## Sepal.Length Petal.Length
## <dbl> <dbl>
## 1 5.1 1.4
## 2 4.9 1.4
## 3 4.7 1.3
## 4 4.6 1.5
## 5 5 1.4
## 6 5.4 1.7
## 7 4.6 1.4
## 8 5 1.5
## 9 4.4 1.4
## 10 4.9 1.5
## # … with 140 more rows
Para combinar verbos necesitaríamos variables auxiliares…
## # A tibble: 9 × 4
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## <dbl> <dbl> <dbl> <dbl>
## 1 7 3.2 4.7 1.4
## 2 6.9 3.1 4.9 1.5
## 3 6.5 2.8 4.6 1.5
## 4 6.6 2.9 4.6 1.3
## 5 6.7 3.1 4.4 1.4
## 6 6.6 3 4.4 1.4
## 7 6.8 2.8 4.8 1.4
## 8 6.7 3 5 1.7
## 9 6.7 3.1 4.7 1.5
…pero en vez de eso podemos usar el operador de piping%>%
## # A tibble: 9 × 4
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## <dbl> <dbl> <dbl> <dbl>
## 1 7 3.2 4.7 1.4
## 2 6.9 3.1 4.9 1.5
## 3 6.5 2.8 4.6 1.5
## 4 6.6 2.9 4.6 1.3
## 5 6.7 3.1 4.4 1.4
## 6 6.6 3 4.4 1.4
## 7 6.8 2.8 4.8 1.4
## 8 6.7 3 5 1.7
## 9 6.7 3.1 4.7 1.5
Creamos iris_b a partir de iris:
sepal creada con mutate.select.iris_b <- iris %>%
mutate(sepal = Sepal.Length*Sepal.Width) %>%
select(-Petal.Length, -Petal.Width)
iris_b## # A tibble: 150 × 4
## Sepal.Length Sepal.Width Species sepal
## <dbl> <dbl> <fct> <dbl>
## 1 5.1 3.5 setosa 17.8
## 2 4.9 3 setosa 14.7
## 3 4.7 3.2 setosa 15.0
## 4 4.6 3.1 setosa 14.3
## 5 5 3.6 setosa 18
## 6 5.4 3.9 setosa 21.1
## 7 4.6 3.4 setosa 15.6
## 8 5 3.4 setosa 17
## 9 4.4 2.9 setosa 12.8
## 10 4.9 3.1 setosa 15.2
## # … with 140 more rows
Renombramos variables haciendo rename(nuevo nombre = nombre actual)
Podemos obteer la media mean de Sepal.Length y Sepal.Width:
## # A tibble: 1 × 2
## msl msw
## <dbl> <dbl>
## 1 5.84 3.06
La tabla resultante tiene una sola fila.
Podemos obtener la media de todos los valores numéricos de iris con:
where(is.numeric) para seleccionar las variables numéricas.across para aplicar una función a las columnas seleccionadas.## # A tibble: 1 × 4
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## <dbl> <dbl> <dbl> <dbl>
## 1 5.84 3.06 3.76 1.20
Podemos obtener valores resumen para cada uno de los valores de una o varias variables categóricas con group_by.
Medias de las variables numéricas para cada valor de Species:
## # A tibble: 3 × 5
## Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 setosa 5.01 3.43 1.46 0.246
## 2 versicolor 5.94 2.77 4.26 1.33
## 3 virginica 6.59 2.97 5.55 2.03
iris %>%
group_by(Species) %>%
summarise(msl = mean(Sepal.Length)) %>%
ggplot(aes(Species, msl)) +
geom_bar(stat = "identity")Usamos geom_bar con stat = "identity" porque la altura de las barras es proporcional al valor de la variable.
tidyverse asume datos ordenados (tidy):
iris and mtcars are examples of tidy data.
## # A tibble: 6 × 11
## religion `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k` `$75-100k`
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Agnostic 27 34 60 81 76 137 122
## 2 Atheist 12 27 37 52 35 70 73
## 3 Buddhist 27 21 30 34 33 58 62
## 4 Catholic 418 617 732 670 638 1116 949
## 5 Don’t kn… 15 14 15 11 10 35 21
## 6 Evangeli… 575 869 1064 982 881 1486 949
## # … with 3 more variables: `$100-150k` <dbl>, `>150k` <dbl>,
## # `Don't know/refused` <dbl>
El paquetetidyr transforma tablas:
pivot_longer.pivot_wider.Los ordenadores entienden tablas largas, los humanos leemos bien tablas anchas.
## # A tibble: 180 × 3
## religion income count
## <chr> <chr> <dbl>
## 1 Agnostic <$10k 27
## 2 Agnostic $10-20k 34
## 3 Agnostic $20-30k 60
## 4 Agnostic $30-40k 81
## 5 Agnostic $40-50k 76
## 6 Agnostic $50-75k 137
## 7 Agnostic $75-100k 122
## 8 Agnostic $100-150k 109
## 9 Agnostic >150k 84
## 10 Agnostic Don't know/refused 96
## # … with 170 more rows
fish_encounters presenta información sobre peces nadando a lo largo de las estaciones de un río. Cada estación monitoriza de manera independiente si un determinado pez ha sido visto en la estación.
## # A tibble: 114 × 3
## fish station seen
## <fct> <fct> <int>
## 1 4842 Release 1
## 2 4842 I80_1 1
## 3 4842 Lisbon 1
## 4 4842 Rstr 1
## 5 4842 Base_TD 1
## 6 4842 BCE 1
## 7 4842 BCW 1
## 8 4842 BCE2 1
## 9 4842 BCW2 1
## 10 4842 MAE 1
## # … with 104 more rows
No todas las combinaciones de peces y estaciones están presentes en la tabla.
Usamos values_fill = list(seen = 0) para fijar igual a cero valores no presentes en la tabla larga.
fish_encounters %>%
pivot_wider(values_from = "seen",
names_from = "station",
values_fill = list(seen = 0))## # A tibble: 19 × 12
## fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE MAW
## <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 4842 1 1 1 1 1 1 1 1 1 1 1
## 2 4843 1 1 1 1 1 1 1 1 1 1 1
## 3 4844 1 1 1 1 1 1 1 1 1 1 1
## 4 4845 1 1 1 1 1 0 0 0 0 0 0
## 5 4847 1 1 1 0 0 0 0 0 0 0 0
## 6 4848 1 1 1 1 0 0 0 0 0 0 0
## 7 4849 1 1 0 0 0 0 0 0 0 0 0
## 8 4850 1 1 0 1 1 1 1 0 0 0 0
## 9 4851 1 1 0 0 0 0 0 0 0 0 0
## 10 4854 1 1 0 0 0 0 0 0 0 0 0
## 11 4855 1 1 1 1 1 0 0 0 0 0 0
## 12 4857 1 1 1 1 1 1 1 1 1 0 0
## 13 4858 1 1 1 1 1 1 1 1 1 1 1
## 14 4859 1 1 1 1 1 0 0 0 0 0 0
## 15 4861 1 1 1 1 1 1 1 1 1 1 1
## 16 4862 1 1 1 1 1 1 1 1 1 0 0
## 17 4863 1 1 0 0 0 0 0 0 0 0 0
## 18 4864 1 1 0 0 0 0 0 0 0 0 0
## 19 4865 1 1 1 0 0 0 0 0 0 0 0
Funciones para leer archivos desde tidyverse.
| lectura | escritura | archivos |
|---|---|---|
read_delim
|
write_delim
|
delimitador genérico |
read_table
|
espacios en blanco | |
read_tsv
|
write_tsv
|
separados por tabulador |
read_csv
|
write_csv
|
archivos .csv (EN)
|
read_csv2
|
write_csv2
|
archivos .csv (ES)
|
Instalamos readxl haciendo:
Función read_excel() para leer archivos Excel.
Herramientas para variables categóricas
Herramientas para cadenas de caracteres
Programación funcional